﻿//-----------------------------------------------------------------------
// <copyright company="www.3WayWebdesign.de">
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
//
// <author>Michael Morbach</author>
// <email>Michael@3waywebdesign.de</email>
// <web>http://www.3waywebdesign.de</web>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Tww.Pixxler.PixxlerService.Interfaces;

namespace Tww.Pixxler.PixxlerService.DataModel
{
    public class CombGUIDGenerator : IIDGenerator
    {
        #region Private Fields

        private static int idcounter = 0;

        #endregion

        /// <summary>
        /// Generate a new <see cref="Guid"/> using the comb algorithm.
        /// </summary>
        public Guid CreateGuid()
        {
            byte[] guidArray = Guid.NewGuid().ToByteArray();

            DateTime baseDate = new DateTime( 1900, 1, 1 );
            DateTime now = DateTime.Now;

            // Get the days and milliseconds which will be used to build the byte string 
            TimeSpan days = new TimeSpan( now.Ticks - baseDate.Ticks );
            TimeSpan msecs = now.TimeOfDay;

            // Convert to a byte array 
            // Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333 
            byte[] daysArray = BitConverter.GetBytes( days.Days );
            byte[] msecsArray = BitConverter.GetBytes( ( long )( msecs.TotalMilliseconds / 3.333333 ) );

            // Reverse the bytes to match SQL Servers ordering 
            Array.Reverse( daysArray );
            Array.Reverse( msecsArray );

            // Copy the bytes into the guid 
            Array.Copy( daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2 );
            Array.Copy( msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4 );

            return new Guid( guidArray );
        }

        /// <summary>
        /// Gibt eine negative 0 basierte ID zurück die als temporäre ID für Objekte genutzt werden kann
        /// </summary>
        /// <returns></returns>
        public int CreateAutoIncrementValue()
        {
            return --idcounter;
        }
    }
}